/*
 * Copyright (c) 2020, EMERGETECH Company Ltd. All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef __VPE_ENCODE_COM_H__
#define __VPE_ENCODE_COM_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include "vpecodec.h"

/*
*  VPE Encoder Parameter Structure
*/
typedef struct VpeEncodeparam{
   
    int width; /* width of input picture */
    int height; /* height of input picture */
    int bit_rate; /* target bit rate in bits per second, Range:[10000,levelMax], Default:1000000 */
    int input_rate_numer; /* Input frame rate numerator, Range:[1,200], Default:30 */
    int input_rate_denom; /* Input frame rate denominator, Range:[1,200], Default:1 */
    char *device; /* device name, such as /dev/transcoderX, Default:/dev/transcoder0 */
    char *enc_params; /* encode parameters group string , refer to Page7 of 'VPE Ffmpeg Plugin Uer Guide V1.0' */
    char *preset; /* encoding preset, Range:superfast/fast/medium/slow/superslow, Default:fast */
    char *profile; /* The HEVC/H.264 profile of the generated stream. 
                      Range: HEVC = main/still/main10  H264 =base/main/high/high10
                      Default: HEVC=main, H264=main*/
    char *level;/* The HEVC/H.264 level of the generated stream. 
                   Range:
                     HEVC=[1.0/2.0/2.1/3.0/3.1/4.0/4.1/5.0/5.1]
                     H264=[1/1b/1.1/1.2/1.3/2/2.1//2.2/3/3.1/3.2/4/4.1/4.2/5/5.1/5.2]
                     Default: HEVC=5.1, H264=5.2 */
    char *enc_codec;/* encoder name string:   hevcenc or h264enc */
    char *force_idr; /* The way to set I frame. It has three modes.
           a. source, the I frames position will keep same with input stream.
           b. keyframe, the I frames position will follow key_frame flag in VpiFrame.
           c. interval:xx, eg, interval:60, the I frames interval is 60.
           Range: source, keyframe, interval:xx .
               interval Range: if lookahead_depth=0: [0...INT_MAX]; if
               lookahead_depth>0: [2...INT_MAX]*/
    char * src_pix_fmt; /* pixel format string of input picture, Range: nv12 yuv420p rgba rgb0 bgra bgr0, Default: nv12 */
    int crf; /* Select the quality for constant quality mode */
    int vbv_max_rate;/*vbv max bitrate*/
    int hwupload_en; /* hardware upload flag, Range:[0,1], Default:1 */
    int alignment; /* row alignment size in bytes: Range:[4,8,16,32,64] */
    int sys_log_level;/*system log level,  0:disable  3:error  4:warning  5:information 6:debug 7:verbose*/
    unsigned int transfer_characteristics;/*VUI param*/
    unsigned int matrix_coefficients;/*VUI param*/
    unsigned int colour_primaries;/*VUI param*/

    int aspect_ratio_num;
    int aspect_ratio_den;

    /* extern device support */
    int ext_device_en;
    device_handle *dev_hndl;
    void *free_cb;

    VpiFrame *frame_ctx;
    /*Set output streams number and set the downscaling size for each stream*/
    char *low_res;
    /*Set output streams number */
    int nb_outputs;
    /*select output streams number */
    int nb_outputs_index;
    int real_framerate;

} VpeEncodeparam;

typedef struct PicRcConfig
{
    int rc_change_rate;          /* target bit rate in bits per second, Range:[10000,levelMax], Default:1000000 */
    int rc_change_cpb_size;      /* HRD Coded Picture Buffer size in bits. (default [0] to enable enable max CPB of current level, suggest 2*bitrate). */
    int rc_change_tolmovbitrate; /* percent tolerance over target bitrate of moving bit rate (default [2000], 0..2000%%).1 */
    int rc_change_vbv_max_rate;  /* target vbv max bitrate in bits per second, Range:[10000,levelMax], Default:1000000 */
} PicRcConfig;

typedef struct VpeCardInfo {
   int device_id; //device_id         , start from 0
   int enc_load; //enc load percentage, 0-100
   int dec_load; //dec load percentage, 0-100
   int total_mem;//total memory
   int free_mem; //total used memory
   int dec_task_num; //dec task num
   int enc_task_num; //enc task num
   float total_dec_resource_artificialhuman; //total resource is defined by human , default is 41
   float total_enc_resource_artificialhuman; //total resource is defined by human , default is 41
   float dec_free_resource_artificialhuman; //dec free resource  is defined by human
   float enc_free_resource_artificialhuman; //enc free resource is defined by human
} VpeCardInfo;

/*
   FUNCTION:                  init encoder
   PARAMETERS:
      [IN] vpe_context: point to vpe encoder context
      [IN] vpe_encode_p: point to encode parameter structure
   RETURN VALUE:
       0: ok   -1: fail

*/
int
Seirios_vpe_encoder_init(VpeContext *vpe_context, VpeEncodeparam *vpe_encode_p);

/*
   FUNCTION:         send video frame to hardware encoder
   PARAMETERS: 
      [IN]  vpe_context: point to vpe encoder context
      [IN]  inframe: point to input video frame
      [OUT] outframe: point to output video frame 
      [IN]  hwupload_en: enable or disable hardware upload
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_send_frame(VpeContext *vpe_ctx, VpiFrame *inframe, VpiFrame *outframe,int  hwupload_en);

/*
   FUNCTION:           set new  encode bit stream rate  
                       set new Picture Buffer size
                       set new percent tolerance over target bitrate of moving bit rate 
   PARAMETERS: 
      [IN] vpe_context: point to vpe encoder context
      [IN] PicRcConfig: point to PicRcConfig structure
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_set_picRc(VpeContext *vpe_ctx,PicRcConfig *rcconfig);

/*
   FUNCTION:             encode frame
   PARAMETERS: 
      [IN] vpe_context: point to vpe encoder context
      [IN] vpe_encode_p: point to input vpi_frame
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_encode_frame(VpeContext *vpe_ctx, VpiFrame *frame);

/*
   FUNCTION:           get output stream of encoder
   PARAMETERS: 
      [IN] vpe_context: point to vpe encoder context
      [OUT] pkt:        point to VpiPacket structure which ship encoded data stream
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_receive_packet(VpeContext *vpe_ctx, VpiPacket *pkt);

/*
   FUNCTION:          close  encoder
   PARAMETERS: 
      [IN] vpe_context: point to vpe encoder context
      [IN] hwupload_en: indicate hwupload is enable or disable
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_encoder_close(VpeContext *vpe_context,int  hwupload_en);

/*
   FUNCTION:        get extradata from encoder
   PARAMETERS: 
      [IN] vpe_context: point to vpe encoder context
      [OUT] vpe_encode_p: point to VpiPacket structure which ship header data from encoder
   RETURN VALUE:
       0: ok   -1: fail
      
*/
int Seirios_vpe_receive_extradata(VpeContext *vpe_ctx, VpiPacket *pkt);
/*
   FUNCTION:        set log callback
   PARAMETERS: 
      [IN] callback 
       0: ok   -1: fail
      
*/

int Seirios_vpe_logcallback(log_callback callback);
/*
   FUNCTION:        get seirios card info
   PARAMETERS: 
      [IN] card_info:            VpeCardInfo arrays
      [IN] max_card_info_size:   VpeCardInfo arrays size
      [IN/OUT]:                  card_numbers
   RETURN VALUE:
       0: ok   -1: fail  
*/

int Seirios_vpe_card_info(VpeCardInfo* card_array,int max_card_array_size,int* card_nums);

/*
   FUNCTION:        set seirios card max transcode ability, calling once is enough for all devices
   PARAMETERS:
      [IN] max_percent:     50-100 (100 equals 720px30fpsx38channels)
      [IN] alloc_type:      0 use one card's resource as many as possible, 1 use many cards's resource as many as possible
   RETURN VALUE: void
*/

void Seirios_set_vpe_card_ability(int max_percent,int alloc_type);

/*
   FUNCTION:        find card resource and create hw devices
   PARAMETERS:
      [IN] width:           width of stream/frame
      [IN] height:          height of stream/frame
      [IN] fps:             fps of stream/frame
      [IN] resource_type:   0 is dec, 1 is enc, 2 is trans ,others is not supported
      [IN] sys_log_level:   log level of vpi & sdk
      RETURN VALUE:
        device_handle: success
        0: fail
*/
device_handle* create_vpe_devices(int width,int height,int fps,int resource_type,int sys_log_level);

/*
  * brief      request an available device index 
  * param[in]  width  pp width array
  * param[in]  height pp height array
  * param[in]  fps   each resoluation fps
  * param[in]  res_count pp resoluation size
  * param[in]  sys_log_level 0-7 
  * return     the postive value is success,  0 is fail
**/

device_handle* create_vpe_pp_devices(int *width,int* height,int fps,int res_count, int sys_log_level);

/*
   FUNCTION:        close hw devices
   PARAMETERS:
      [IN] p_dh:    device_handle
      RETURN VALUE: void
*/
void close_vpe_devices(device_handle* p_dh);

#ifdef __cplusplus
}
#endif

#endif


